import json
import os
import re
from urllib.parse import unquote

import jsonpath
import requests
from faker import Faker
from api.client import HttpClient
from common.logger import Logger
from common.read_yaml import ReadYaml_By_Root_Dict
from common.utils import Utils


fake = Faker(locale='zh_CN')
utils = Utils()
requests.packages.urllib3.disable_warnings()
env = ReadYaml_By_Root_Dict("configs/environment_var.yml").get_yaml_data()  # 读取数据
business_params = ReadYaml_By_Root_Dict("case_online/business_payload.yml").get_yaml_data()  # 读取业务数据入参


def jp(obj, expr, result_type='VALUE', debug=0, use_eval=True):
    Logger.info(f'jsonpath表达式：{expr}')
    return jsonpath.jsonpath(obj, expr, result_type='VALUE', debug=0, use_eval=True)


class MyScm(HttpClient):
    def __init__(self, session=None):
        self.session = session
        super().__init__(self.session)
        # 获取环境参数，然后得到环境参数的对应的值
        environ = self.env_flag
        self.__tenant = jp(env,f'$.{environ}.app_tenant_id')[0]
        self.__app_code = jp(env,f'$.{environ}.app_code')[0]
        self.__passport = jp(env,f'$.{environ}.business_host.passport')[0]
        self.__bms = jp(env,f'$.{environ}.business_host.bms')[0]
        self.__kfapi = jp(env,f'$.{environ}.business_host.kfapi')[0]
        self.__kefu = jp(env,f'$.{environ}.business_host.kefu')[0]
        self.users = jp(env,f'$.{environ}.users')[0] # 用户信息，字典：{user:password}
        self.__header = {"Connection": "keep-alive",
                       "Content-Length": "70",
                       "sec-ch-ua": '"Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"',
                       "Accept": "application/json, text/plain, */*",
                       "sec-ch-ua-mobile": "?0",
                       "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36",
                       "Content-Type": "application/x-www-form-urlencoded",
                       "Sec-Fetch-Site": "same-origin",
                       "Sec-Fetch-Mode": "cors",
                       "Sec-Fetch-Dest": "empty",
                       "Accept-Encoding": "gzip, deflate, br",
                       "Accept-Language": "zh-CN,zh;q=0.9",
                       }

    # 登录
    def login_myscm(self, user, password):
        self.request = self.session
        # URL = f'https://passport-test.myyscm.com/api/login-v2'
        URL = f'{self.__passport}/api/login-v2'
        data = f"tenantCode={self.__tenant}&username={user}&password={password}&captchaCode="
        r = self.request.post(URL, headers=self.__header, data=data, verify=False)
        print(f'login_myscm:{r.json()}')
        dict_cookies: dict = requests.utils.dict_from_cookiejar(r.cookies)
        # 获取关键参数sid，ticket
        sid = dict_cookies.get('PASSPORTSID2')
        ticket = r.json()['ticket']
        self.sid = sid
        self.ticket = ticket
        return_dict = {"sid": sid, "ticket": ticket}
        return return_dict

    # 获取Authorization
    def get_Authorization(self):
        url = f'{self.__bms}/m/common/check-ticket?smp=CustomerService.TaskApproveSetting&_smp=CustomerService.TaskApproveSetting'
        # payload = {"ticket":"1665825572BiOFgZ","sid":sid,"o":tenant}
        payload = {"ticket": self.ticket, "sid": self.sid, "o": self.__tenant}
        r = self.request.post(url, json=payload, verify=False)
        self.Authorization = r.headers.get("Authorization")
        print(f'get_Authorization:{r.json()}')
        print(f'get_Authorization:{self.Authorization}')
        # return Authorization

    # 启用工作流审批
    def enable_bpm_approve(self):
        url = f"{self.__bms}/m/workflow/scenario/enabled?smp=CustomerService.TaskApproveSetting&_smp=CustomerService.TaskApproveSetting"
        headers = {
            "Accept": "application/json, text/plain, */*",
            "X-YL-Tenant-Code": self.__tenant,
            "Authorization": self.Authorization,
            # "Authorization": "Bearer eyJ0eXBlIjoiSldUIiwiYWxnbyI6InNoYTI1NiIsImNyZWF0ZWRBdCI6MTY2NTgyNDc4NiwiZXhwaXJlVGltZSI6MzAwLCJyZWZyZXNoRXhwaXJlVGltZSI6NzIwMH0.eyJhY2NvdW50IjoicmV0ZXN0aW5nIiwiY29tcGFueUlEIjoiMTFiMTFkYjQtZTkwNy00ZjFmLTg4MzUtYjlkYWFiNmUxZjIzIiwibG9naW5VdWlkIjoiMjAyMjEwMTUxNDAzMTE2MzRhNGQxZmU2OTQ4IiwibW9iaWxlIjoiMTY2NjY2NjY2NjYiLCJvcGVuSWQiOiJjN2ZkZWVjY2JlMGI2YWQyNzM4NmQxMjMwYzg0NTUwODM3NWQiLCJvcmdJRCI6IjExYjExZGI0LWU5MDctNGYxZi04ODM1LWI5ZGFhYjZlMWYyMyIsIm9yZ05hbWUiOiJcdTY2N2FcdTYxNjdcdTcyNjlcdTRlMWFcdTk2YzZcdTU2ZTIiLCJvcmdOYW1lUGF0aCI6Ilx1NjY3YVx1NjE2N1x1NzI2OVx1NGUxYVx1OTZjNlx1NTZlMiIsInBvc3ROYW1lIjoiXHU2ZDRiXHU4YmQ1XHU2NTcwXHU2MzZlXHU1Yzk3XHU0ZjRkXHU1NDBkXHU3OWYwXHU2ZDRiXHU4YmQ1XHU2NTcwXHU2MzZlXHU2NzAwXHU1OTI3XHU5NTdmXHU1ZWE2XHU2ZDRiXHU4YmQ1XHU2NzAwXHU1OTI3XHU5NTdmXHU1ZWE2XHU2ZDRiXHU4YmQ1XHU2NzAwXHU1OTI3XHU5NTdmXHU1ZWE2XHU2ZDRiXHU4YmQ1XHU2NzAwXHU1OTI3XHU5NTdmXHU1ZWE2XHU2ZDRiXHU4YmQ1XHU2NzAwXHU1OTI3XHU5NTdmXHU1ZWE2XHU2ZDRiXHU4YmQ1XHU2NzAwXHU1OTI3XHU5NTdmXHU1ZWE2XHU2ZDRiXHU4YmQ1XHU2NzAwMSIsInRlbmFudENvZGUiOiJyZXRlc3RpbmciLCJ0ZW5hbnRJRCI6IjExYjExZGI0LWU5MDctNGYxZi04ODM1LWI5ZGFhYjZlMWYyMyIsInRlbmFudE5hbWUiOiJcdTY2N2FcdTYxNjdcdTcyNjlcdTRlMWFcdTk2YzZcdTU2ZTIiLCJ1bmlvbklkIjoiODUwZGNhM2YzM2M5YmFmY2Y2MTRhNzUyYzJlZmI0OWNlNjhhIiwidXNlcklEIjoiMjJiMTFkYjQtZTkwNy00ZjFmLTg4MzUtYjlkYWFiNmUxZjIzIiwidXNlcklkIjoiMjJiMTFkYjQtZTkwNy00ZjFmLTg4MzUtYjlkYWFiNmUxZjIzIiwidXNlclR5cGUiOiJTVVBFUl9BRE1JTiIsInVzZXJuYW1lIjoiXHU4ZDg1XHU3ZWE3XHU3NTI4XHU2MjM3In0.AV16e-mMbHFKlDeKtKKljnAO9EQzIPJjtnv7cr0hqOI",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
        }
        payload = {"id": "39ea8de6-cb5f-4999-8438-830c2cbd44e1", "enabled": 1}
        r = self.request.post(url=url, headers=headers, json=payload, verify=False)
        print(f'enable_bpm_approve:{r.json()}')

    def create_task(self, task_name):
        """
        创建维修任务
        """
        url = f'{self.__kfapi}/{self.__tenant}/bk/task/task/batch-assign?o={self.__tenant}&_smp=CustomerService.TaskHandle&_ac=CustomerService&token={self.sid}'
        task_id = fake.uuid4()
        print(f'生成任务ID：{task_id}')
        payload = jp(business_params,f'$.{self.env_flag}.repair_order')[0]  # 从case_online/business_payload.yml文件中获取对应环境业务数据入参
        utils.update_json_by_jsonpath(payload, '$.tasks[0].subject', task_name)  # 替换掉任务名称
        utils.update_json_by_jsonpath(payload, '$.tasks[0].task_id', task_id)  # 替换掉task_id

        self.__header.update({'Content-Type': 'application/json;charset=UTF-8'})
        r = self.request.post(url, headers=self.__header, json=payload, verify=False)
        print(r.json())
        return r

    def cancel_task(self, task_id):
        """
        取消维修任务
        """
        url = f'{self.__kfapi}/{self.__tenant}/bk/tasks/cancel?o={self.__tenant}&_smp=CustomerService.TaskHandle&_ac=CustomerService&token={self.sid}'
        payload = f'task_id={task_id}&cancel_reason=123&is_push_owner=0&owner_content=&o={self.__tenant}'
        header = {
            "Accept": "application/json, text/plain, */*",
            "X-YL-Tenant-Code": self.__tenant,
            "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36"
        }
        r = self.request.post(url, headers=header, data=payload, verify=False)
        # 获取发起流程的url，并解码，方便获取中文业务类型
        workflow_url = unquote(r.json()['data']['workflow_url'])
        print(f'cancel_task: {r.json()}')
        return workflow_url

    # 流程中转页面
    def transfer_process(self, transfer_url):
        """
        流程中转页面请求，获取跳转流程发起或流程审批页面地址
        Args:
            transfer_url: 流程中转url

        Returns:流程发起或者流程审批的url：/flowinstance/approval/index或/flowinstance/process/create

        """
        url = transfer_url
        r = self.request.get(url, verify=False, allow_redirects=False)
        create_or_approve_url = r.headers['Location']
        print(f'transfer_process:{create_or_approve_url}')
        return create_or_approve_url

    def create_process(self, create_or_approve_url):
        """
        通过创建流程url，打开流程
        Args:
            create_or_approve_url:

        Returns:

        """
        url = create_or_approve_url
        r = self.request.post(url, allow_redirects=False)
        print(r.text)

    def initiation_process(self):
        url = f'https://bpm-flow-test-new.myyscm.com/{self.__tenant}/yl/flowinstance/process/get-process-info?flow_template_id={self.flow_template_id}&package_id={self.package_id}&business_id={self.business_id}&started_organization_id=&o=retesting&_=1665889925861'
        r = self.request.get(url, verify=False)
        print(f"initiation_process:{r.json()}")

    def get_instance_id_by_task_id(self, task_id, status='审批中'):
        """
        通过task_id获取流程实例id，可以一个task可能有多次发起的流程
        Args:
            task_id: 任务ID
            status: 状态名称，中文：审批中、已作废等等。默认状态查询审批中的流程id

        Returns:对应任务id和状态的流程实例id

        """
        url = f'{self.__kefu}/{self.__tenant}/dailyservice/task-approve/list?task_id={task_id}&_smp=CustomerService.TaskRegist&pageSize=10&page=1&o={self.__tenant}&_=1666493730170'
        r = self.request.get(url, verify=False)
        print(f'get_instance_id_by_task_id:{r.json()}')
        instance_id = jp(r.json(), f"$..items[?(@.status=='{status}')].instance_id")[0]
        return instance_id

    def get_transfer_url(self, instance_id):
        url = f'{self.__kefu}/{self.__tenant}/dailyservice/task-approve/approve-detail-url?_smp=CustomerService.TaskRegist'
        payload = f'instance_id={instance_id}&o={self.__tenant}'
        header = {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
        r = self.request.post(url, data=payload, headers=header, verify=False)
        print(f'get_approve_url:{r.json()}')
        transfer_url = jp(r.json(), '$..approve_detail_url')[0]
        return transfer_url

    def business_initiate(self, user, passwd, task_name):
        myscm = self
        # myscm.login_myscm('retesting', 'retesting', 'Sh123456')
        myscm.login_myscm(user, passwd)
        myscm.get_Authorization()
        myscm.enable_bpm_approve()
        task_resp = myscm.create_task(task_name)
        task_id = task_resp.json()['data']['task_ids'][0]
        myscm.cancel_task(task_id)
        # task_id = 'fa3fb912-5b21-4c85-83f7-0fc08c208586'
        transfer_url = myscm.cancel_task(task_id)
        create_url = myscm.transfer_process(transfer_url)  # 发起跳转返回给流程使用
        myscm_sess = myscm.session  # session返回给流程平台使用
        return myscm_sess, create_url, task_id

    def business_approve(self,user, passwd, task_id):
        myscm = self
        myscm.login_myscm(user, passwd)
        myscm.get_Authorization()
        myscm.enable_bpm_approve()
        instance_id = myscm.get_instance_id_by_task_id(task_id)
        transfer_url = myscm.get_transfer_url(instance_id)
        approve_url = myscm.transfer_process(transfer_url)
        myscm_sess = myscm.session  # session返回给流程平台使用
        return myscm_sess, approve_url

if __name__ == "__main__":
    demo_dict = {"head_task_type":"维修","tasks":[{"repair_type":"房间维修","complaint_business_type":"","class_full_name":"服务类-销售服务-销售承诺","class_name":"销售承诺","problem_list":[{"id":"3a0434ae-018f-5031-4e79-7661e0a4ef73","sort":"1","is_for_decorated":"1"}],"problem_remark":"","subject":"维修任务主题","praise_user":[],"accept_corp_name":"正荣公司","task_id":"39f3f94a-67a5-daba-5ac3-c5ff206b5070","corp_id":"39d20a12-56b6-bc2a-974d-ca438a26f0e8",}],"hideTaskAddMaintainer":0,"create_source":"后台"}
    Utils().update_json_by_jsonpath(demo_dict,'$.tasks[0].subject','test000001')
    print(demo_dict)
    # print(env.get(os.environ["api_test_env"]))
    # myscm = MyScm()
    # r = myscm.login_myscm('retesting', 'retesting', 'Sh123456')
    # Authorization = myscm.get_Authorization('retesting')
    # myscm.enable_bpm_approve()
    # # task_resp = create_task(sid,'测试名称123')
    # # task_id = task_resp.json()['data']['task_ids'][0]
    #
    # # transfer_url = myscm.cancel_task("f6d56f7b-1b6c-4d56-a923-d0c8c9748c5e")
    # # create_process_url = myscm.transfer_process(transfer_url)
    # # myscm.create_process(create_process_url)
    # # myscm.initiation_process()
    #
    # instance_id = myscm.get_instance_id_by_task_id("fa3fb912-5b21-4c85-83f7-0fc08c208586")
    # approve_url = myscm.get_transfer_url(instance_id)
    # create_or_approve_url = myscm.transfer_process(approve_url)
